package com.zshan.clinic.admin.service.config;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.ObjectMetadata;
import com.idrsolutions.image.png.PngCompressor;
import com.zshan.clinic.admin.constant.OssProperties;
import com.zshan.clinic.admin.constant.PropertiesUtil;
import com.zshan.clinic.common.enums.FileSuffixTypeEnum;
import com.zshan.clinic.common.enums.FileTypeEnum;
import com.zshan.clinic.common.enums.YesOrNoEnum;
import com.zshan.clinic.common.exception.BusinessFailException;
import com.zshan.clinic.common.util.file.FileUtils;
import com.zshan.clinic.common.util.string.StringUtil;
import com.zshan.clinic.common.util.uuid.IdBuilder;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.text.SimpleDateFormat;
import java.util.Date;


/**
 * 文件上传Service
 */
@Slf4j
public class FileUploadService {

    private final OSS ossClient;

    private final OssProperties ossProperties;

    private final PropertiesUtil propertiesUtil;

    public FileUploadService(OSS ossClient, OssProperties ossProperties,PropertiesUtil propertiesUtil) {
        this.ossClient = ossClient;
        this.ossProperties = ossProperties;
        this.propertiesUtil = propertiesUtil;
    }


    /**
     * 文件上传
     * 注：阿里云OSS文件上传官方文档链接：https://help.aliyun.com/document_detail/84781.html?spm=a2c4g.11186623.6.749.11987a7dRYVSzn
     * @param uploadFile
     * @param userId
     * @param userName
     * @return
     */
    public String uploadToOss(File uploadFile, Long userId, String userName,String isCompress,FileSuffixTypeEnum fileSuffixTypeEnum){
        if(uploadFile == null){
            return null;
        }
        log.info("文件上传阿里云OSS,文件名称:{},上传用户ID:{},上传用户:{},宽度:{},高度:{}",uploadFile.getName(),userId,userName);
        String returnImgeUrl = null;
        try{
            // 获取文件原名称
            String fileName = uploadFile.getName();
            String fileType = fileSuffixTypeEnum.getValue();
            if(StringUtil.isBlank(isCompress)){
                isCompress = YesOrNoEnum.YES.getValue();
            }
            if(FileTypeEnum.IMG.getValue().equals(fileSuffixTypeEnum.getType())){
                if(YesOrNoEnum.YES.getValue().equals(isCompress)){
                    log.info("开始压缩文件,文件大小:{}",uploadFile.length());
                    if (FileSuffixTypeEnum.jpeg.getValue().equals(fileType) || FileSuffixTypeEnum.jpg.getValue().equals(fileType)){
                        /**
                         * 制定质量比
                         */
                        Thumbnails.of(uploadFile)
                                .scale(1f)
                                .outputQuality(0.8f)
                                .toFile(uploadFile);
                    }else if(FileSuffixTypeEnum.png.getValue().equals(fileType)){
                        PngCompressor.compress(uploadFile,uploadFile);
                    }
                    log.info("图片压缩完成,文件大小:{}",uploadFile.length());
                }
            }
            log.info(">>>>>>>>>>初始化阿里云文件上传SDK>>>>>>>>>>");
            ObjectMetadata meta = new ObjectMetadata();
            // 获取oss的Bucket名称
            String bucketName = ossProperties.getBucketName();
            // 获取oss目标文件夹
            String filehost = ossProperties.getFileHost();
            // 构建日期路径, 例如：OSS目标文件夹/2020/10/31/文件名
            String filePath = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
            // 文件上传的路径地址
            String uploadImgeUrl = filehost + "/" + filePath + "/" + fileName;
            // 返回图片上传后返回的url
            if(FileTypeEnum.IMG.getValue().equals(fileSuffixTypeEnum.getType())){
                meta.setContentType("image/"+fileSuffixTypeEnum.getText());
            }else{
                meta.setContentType("application/octet-stream");
            }
            log.info(">>>>>>>>>>初始化阿里云文件上传SDK>>>>>>>>>>");
            //文件上传至阿里云OSS
            try (FileInputStream fis = new FileInputStream(uploadFile)) {
                ossClient.putObject(bucketName, uploadImgeUrl, fis, meta);
                ossClient.setObjectAcl(bucketName, uploadImgeUrl, CannedAccessControlList.PublicRead);
            }
            log.info(">>>>>>>>>>文件上传完成>>>>>>>>>>");
            // 获取文件上传后的图片返回地址
            returnImgeUrl = ossProperties.getDomain() + "/" + uploadImgeUrl;
            //保存文件上传记录
        }catch (Exception e){
            log.error("文件上传失败",e);
            throw new BusinessFailException("文件上传失败");
        }
        return returnImgeUrl;
    }



    /**
     * 文件上传
     * @param uploadFile 原始文件
     * @param userId 上传人ID
     * @param userName 上传人名称
     * @return
     */
    public String uploadMultipartFile(MultipartFile uploadFile, Long userId, String userName, String isCompress) {
        // 校验图片格式
        FileSuffixTypeEnum fileSuffixTypeEnum = FileSuffixTypeEnum.get(uploadFile.getOriginalFilename().substring(uploadFile.getOriginalFilename().lastIndexOf(".")));
        if(fileSuffixTypeEnum == null){
            throw new BusinessFailException("文件格式错误");
        }
        File file = null;
        try{
            /**
             * 文件转换
             */
            file = new File(propertiesUtil.getFileFolder() + IdBuilder.getID() + fileSuffixTypeEnum.getValue());
            FileUtils.multipartFileToFile(uploadFile,file);
        } catch (Exception e){
            throw new BusinessFailException("文件转换异常");
        }
        return uploadToOss(file,userId,userName,isCompress,fileSuffixTypeEnum);
    }
}

